﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using RebEngine.GameComponents;
using System.Collections;
using RebEngine.Managers;
using Microsoft.Xna.Framework.Graphics;

namespace RebEngine.SceneObject.SceneGraph
{
    public class Node : IComparable
    {
        public string key;
        static VertexPositionColor[] verts = new VertexPositionColor[8];
        static short[] indices = new short[]
            {
                0, 1,
                1, 2,
                2, 3,
                3, 0,
                0, 4,
                1, 5,
                2, 6,
                3, 7,
                4, 5,
                5, 6,
                6, 7,
                7, 4,
            };

        static BasicEffect effect;

        protected NodeList _nodes;
        public NodeList Nodes
        {
            get { return _nodes; }
            set { _nodes = value; }
        }

        public void Sort()
        {
            _nodes.Sort();
        }

        public Node(string name)
        {
            key = name;
            _nodes = new NodeList();
        }

        public void AddNode(Node newNode)
        {
            _nodes.Add(newNode);
        }

        public Node GetNode(string key)
        {
            foreach (Node node in _nodes)
            {
                if (node.key == key)
                    return node;
            }

            return null;
        }

        int IComparable.CompareTo(object obj)
        {
            SceneObjectNode node1 = (SceneObjectNode)this; 
            SceneObjectNode node2 = (SceneObjectNode)obj;

            if (node1.SceneObject.Distance < node2.SceneObject.Distance)
                return -1;
            else if (node1.SceneObject.Distance > node2.SceneObject.Distance)
                return 1;
            else
                return 0;
        }
        public virtual void Update(GameTime gameTime)
        {
            _nodes.ForEach(
                delegate(Node node)
                {
                    node.Update(gameTime);
                });
        }

        public void UnloadContent(RebSceneObject obj)
        {
            _nodes.ForEach(
                delegate(Node node)
                {
                    if (((SceneObjectNode)node).SceneObject == obj)
                    {
                        node.UnloadContent();
                        _nodes.Remove(node);
                    }
                });

        }

        public virtual void UnloadContent()
        {
            _nodes.ForEach(
               delegate(Node node)
               {
                   node.UnloadContent();
               });
            _nodes.Clear();
        }

        public virtual void LoadContent()
        {
            _nodes.ForEach(
               delegate(Node node)
               {
                   node.LoadContent();
               });
        }

        public virtual void Draw(GameTime gameTime)
        {
            _nodes.ForEach(
               delegate(Node node)
               {
                   /*if((SceneGraphManager.DebugDrawing) && (((SceneObjectNode)node).SceneObject.BoundingBox != null))
                   {
                       Render(((SceneObjectNode)node).SceneObject.BoundingBox, Color.White);
                   }*/
                   if (CameraManager.ActiveCamera.Frustrum != null)
                   {
                       if (CameraManager.ActiveCamera.Frustrum.Intersects(((SceneObjectNode)node).SceneObject.BoundingBox))
                       {
                           node.Draw(gameTime);
                       }
                   }/*
                   if ((SceneGraphManager.DebugDrawing) && ((SceneObjectNode)node).Nodes.Count > 0)
                   {
                       foreach(var temp in ((SceneObjectNode)node).Nodes)
                       {
                            Render(((SceneObjectNode)temp).SceneObject.BoundingBox, Color.HotPink);
                       }
                   }*/
               });
        }

        public static void Render(BoundingBox box, Color color)
        {
            if (effect == null)
            {
                effect = new BasicEffect(EngineManager.Device);
                effect.VertexColorEnabled = true;
                effect.LightingEnabled = false;
            }

            Vector3[] corners = box.GetCorners();
            for (int i = 0; i < 8; i++)
            {
                verts[i].Position = corners[i];
                verts[i].Color = color;
            }

            //EngineManager.Device.VertexDeclaration = vertDecl;

            effect.View = CameraManager.ActiveCamera.View;
            effect.Projection = CameraManager.ActiveCamera.Projection;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();

                EngineManager.Device.DrawUserIndexedPrimitives(
                    PrimitiveType.LineList,
                    verts,
                    0,
                    8,
                    indices,
                    0,
                    indices.Length / 2);

                
            }
        }
    }
}
